package com.zim.aliot.service.impl;

import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import com.zim.aliot.client.LcxClient;
import com.zim.aliot.constant.RedisConstant;
import com.zim.aliot.dao.CarsRepository;
import com.zim.aliot.dataobject.CarsDo;
import com.zim.aliot.exception.IotApiException;
import com.zim.aliot.lcx.LcxResult;
import com.zim.aliot.service.CarsService;
import com.zim.aliot.vo.VehicleVO;

import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
public class CarsServiceImpl implements CarsService {
    @Autowired
    private CarsRepository carsRepository;
    
    @Resource
    private RedisTemplate<String, CarsDo> redisTemplate;
    
    @Autowired
    private MongoTemplate mgt;
    
    @Autowired
    private LcxClient lcxClient;

    @Override
    public CarsDo save(CarsDo carsDo) {
         try {
            return carsRepository.save(carsDo);
        } catch (Exception e) {
           log.error("[mongo写入失败]:{}",e.getMessage());
           return null;
        }
    }

    @Override
    public CarsDo find(String deviceName) {
        ValueOperations<String, CarsDo> operations = redisTemplate.opsForValue();
        boolean hasKey = redisTemplate.hasKey(deviceName);
        if (hasKey) {
            return operations.get(deviceName);
        }else {
            Optional<CarsDo> carsDo = carsRepository.findById(deviceName);
            CarsDo resCarsDo = carsDo.get();
            operations.set(deviceName, resCarsDo,RedisConstant.EXPIRE,TimeUnit.SECONDS);
            return resCarsDo;
        }
    }
 
	@Override
	public List<VehicleVO> getHisInfo(String vin, long timeStart, long timeEnd) {
		try {
			Criteria c1= Criteria.where("time").gte(timeStart).lte(timeEnd).and("car_unique_id").is(vin);
			List<VehicleVO> vehicleVO = mgt.find( new Query(c1), VehicleVO.class);
			return vehicleVO;
		} catch (Exception e) {
			log.error("【mongo读取数据失败】:{}",e.getMessage());
	        return null;
		}
	}

	@Override
	public CarsDo findByVin(String vin) {	
		ValueOperations<String, CarsDo> operations = redisTemplate.opsForValue();
	    boolean hasKey = redisTemplate.hasKey(vin);
        if (hasKey) {
            return operations.get(vin);
        }else {      	
    		CarsDo carsDo = carsRepository.findByVin(vin);
            operations.set(vin, carsDo,RedisConstant.EXPIRE,TimeUnit.SECONDS);
            return carsDo;
            
        }
		
	}

	@Override
	public boolean bandCars(int supplierNo,String equipMentId,String vin,String carSn) {
		LcxResult LcxResult = lcxClient.bandCars(supplierNo, equipMentId, vin, carSn);
		if(null != LcxResult && 0 == LcxResult.getResult()) {
			return true;
		}else {
			log.error("[ 车辆绑定推送失败 ]:{}",LcxResult);
			throw new IotApiException(LcxResult.getResult(),LcxResult.getMsg());
		}
		
	}

	@Override
	public boolean unBandCar(int supplierNo,String vin) {
		LcxResult LcxResult = lcxClient.unBandCars(supplierNo, vin);
		if(null != LcxResult && 0 == LcxResult.getResult()) {
			return true;
		}else {
			log.error("[车辆解绑推送失败]:{}",LcxResult);
			throw new IotApiException(LcxResult.getResult(),LcxResult.getMsg());
		}
	}

	
}
